Imports System.Text.RegularExpressions

Public Class Marker
    Private m_ID As String
    Private m_DoNotModify As Boolean
    Private m_source As String
    Private m_commentHandler As GenerateLineComment


    Public Delegate Function GenerateLineComment() As String

    Public Sub New(ByVal id As String)
        Me.m_ID = id
        Me.m_DoNotModify = False
    End Sub

    Public Sub New(ByVal id As String, ByVal sourceFragment As String, ByVal commentHandler As GenerateLineComment)
        Me.m_ID = id
        Me.m_DoNotModify = False
        Me.m_commentHandler = commentHandler
        Me.m_source = WrapFragmentInMarker(sourceFragment)
    End Sub

    Public Sub Update(ByVal source As String, ByVal commentHandler As GenerateLineComment)
        Me.m_commentHandler = commentHandler
        Me.m_source = WrapFragmentInMarker(source)
    End Sub

    Public Sub New(ByVal sourceFragment As String, ByVal commentHandler As GenerateLineComment)
        'compensate for shaved off comment and extra new line characters at the end (to match closecommand)
        Me.m_source = commentHandler.Invoke() & " " & sourceFragment & vbCrLf & vbCrLf
        Me.GetID()
        Me.GetDoNotModify()
    End Sub

    Private Function WrapFragmentInMarker(ByVal frag As String) As String
        Return OpenCommand() & vbCrLf & frag & vbCrLf & CloseCommand()
    End Function

    Private Function OpenCommand() As String
        Dim cmd As String = ""
        cmd = cmd & m_commentHandler.Invoke() & " " & Constants.CMD_OPEN_METADATA & vbCrLf
        cmd = cmd & m_commentHandler.Invoke() & " " & Constants.CMD_ID & " = " & Me.m_ID & vbCrLf
        cmd = cmd & m_commentHandler.Invoke() & " " & Constants.CMD_MOD & " = " & Me.m_DoNotModify.ToString()
        Return cmd
    End Function

    Private Function CloseCommand() As String
        Dim cmd As String = ""
        cmd = cmd & m_commentHandler.Invoke() & " " & Constants.CMD_CLOSE_METADATA & vbCrLf & vbCrLf
        Return cmd
    End Function

    Private Sub GetID()
        Dim startIndex As Integer = 0
        Dim eqIndex As Integer = 0
        Dim endIndex As Integer = 0
        startIndex = m_source.IndexOf(Constants.CMD_ID)
        If startIndex < 0 Then Return
        eqIndex = m_source.IndexOf("=", startIndex + Constants.CMD_ID.Length)
        If eqIndex < 0 Then Return
        endIndex = m_source.IndexOf(vbCrLf, eqIndex + 1)
        If endIndex < 0 Then Return
        Me.m_ID = m_source.Substring(eqIndex + 1, endIndex - eqIndex).Trim()
    End Sub

    Private Sub GetDoNotModify()
        Me.m_DoNotModify = False
        Dim startIndex As Integer = 0
        Dim eqIndex As Integer = 0
        Dim endIndex As Integer = 0
        startIndex = m_source.IndexOf(Constants.CMD_MOD)
        If startIndex < 0 Then Return
        eqIndex = m_source.IndexOf("=", startIndex + Constants.CMD_MOD.Length)
        If eqIndex < 0 Then Return
        endIndex = m_source.IndexOf(vbCrLf, eqIndex + 1)
        If endIndex < 0 Then Return
        Dim id As String = m_source.Substring(eqIndex + 1, endIndex - eqIndex)
        If [String].Compare(id.Trim(), "true", True) = 0 Then
            Me.m_DoNotModify = True
        End If
    End Sub

    Public ReadOnly Property ID() As String
        Get
            Return Me.m_ID
        End Get
    End Property

    Public ReadOnly Property DoNotModify() As Boolean
        Get
            Return Me.m_DoNotModify
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Me.m_source
    End Function
End Class
